using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace BindingFlagsSnippet
{
    class Example
    {
        static void Main()
        {
            Type type = typeof(List<int>);
            ConstructorInfo[] methods = type.GetConstructors(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.Instance);

            foreach (ConstructorInfo item in methods)
            {
                StringBuilder builder = new StringBuilder();
                builder.Append(GetVisibility(item) + " ");
                builder.Append(item.IsStatic ? "static " : string.Empty);
                builder.Append(GetMethodName(item) + " ");
                builder.Append("(" + GetParams(item) + ")");
                Console.WriteLine(builder.ToString());
            }
            Console.ReadKey();
        }
        public static string GetVisibility(ConstructorInfo method)
        {
            return
                method.IsPublic ? "public" :
                method.IsPrivate ? "private" :
                method.IsAssembly ? "internal" :
                method.IsFamily ? "protected" :
                method.IsFamilyOrAssembly ? "protected internal" :
                null;
        }


        // 判断方法是否为泛型方法，并且返回泛型名称
        public static string GetMethodName(ConstructorInfo method)
        {
            if (!method.IsGenericMethod)
                return method.Name;
            Type[] types = method.GetGenericArguments();
            string str = method.Name + "<";
            for (int i = 0; i < types.Length; i++)
            {
                str += types[i].Name;
                if (i < types.Length - 1)
                    str += ",";
            }
            str += ">";
            return str;
        }

        // 解析方法的参数
        public static string GetParams(ConstructorInfo method)
        {
            ParameterInfo[] parameters = method.GetParameters();
            if (parameters.Length == 0)
                return string.Empty;

            int length = parameters.Length - 1;
            StringBuilder str = new StringBuilder();
            for (int i = 0; i <= length; i++)
            {
                str.Append(InRefOut(parameters[i]) + " ");
                // 这里不对复杂类型等做处理
                str.Append(GetParamType(parameters[i]) + " ");
                str.Append(parameters[i].Name);
                str.Append(HasValue(parameters[i]) + " ");
                if (i < length)
                    str.Append(",");
            }
            return str.ToString();
        }

        public static string InRefOut(ParameterInfo parameter)
        {
            // in、ref、out ，类型后面会带有 & 符号
            if (parameter.ParameterType.Name.EndsWith("&"))
            {
                return
                    parameter.IsIn ? "in" :
                    parameter.IsOut ? "out" :
                    "ref";
            }
            if (parameter.GetCustomAttributes().Any(x => x.GetType() == typeof(ParamArrayAttribute)))
                return "params";
            return string.Empty;
        }

        // 获取类型
        public static string GetParamType(ParameterInfo parameter)
        {
            string typeName = parameter.ParameterType.Name;
            if (typeName.EndsWith("&"))
                typeName = typeName.Substring(0, typeName.Length - 1);
            return typeName;
        }

        // 是否为可选参数，是否有默认值
        public static string HasValue(ParameterInfo parameter)
        {
            if (!parameter.IsOptional)
                return string.Empty;
            object value = parameter.DefaultValue;
            return " = " + value.ToString();
        }
    }
}